home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 February: Tool Chest / Dev.CD Feb 99 TC.toast / What's New? / Development Kits / Mac OS USB v1.1f3 DDK / Examples / PrinterClassDriver / usbprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-07  |  7.6 KB  |  327 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        usbprint.c
  3.  
  4.     Contains:    usb printer class device communication
  5.                     (installed in UnitTable)
  6.  
  7.     Copyright: 1998 by Apple Computer, Inc., all rights reserved.
  8.  
  9. */
  10. #include "PrinterClassDriver.h"
  11.  
  12. #ifndef __DEVICES__
  13. #include <devices.h>
  14. #endif
  15.  
  16. #ifndef __FILES__
  17. #include <files.h>
  18. #endif
  19.  
  20. #define kMaskLowByte    0x0FF
  21.  
  22. extern pascal OSErr    DRVRDone( OSErr err, DCtlPtr ctl, IOParamPtr pb );
  23. static void AbortActive( CntrlParam *pb, DCtlPtr clt );
  24.  
  25. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  26.     Name:        GetPrinterStruct
  27.  
  28.     Input Parameters:    IOParamPtr        i/o parameter block
  29.         
  30.     Output Parameters:
  31.         usbPrinterPBStruct    * pointer to the device
  32.         
  33.     Description:
  34.         Given a device control block, map it to a usb device's data structure
  35.  
  36.     Change History:
  37.         28 Feb 1998,    oja:        Original version.
  38. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  39. static struct usbPrinterPBStruct    *
  40. GetPrinterStruct( DCtlPtr ctl )
  41. {
  42.     return (struct usbPrinterPBStruct *) ctl->dCtlStorage;
  43. }
  44.  
  45. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  46.     Name:        Read
  47.  
  48.     Input Parameters:
  49.         
  50.     Output Parameters:
  51.         <none>
  52.         
  53.     Description:
  54.         
  55.     Change History:
  56.         11 Jun 1998,    oja:        return pb->ioResult, not usbprint->in.usbStatus
  57.          4 Apr 1998,    oja:        Fix handshaking: do not set pb->ioResult
  58.         28 Feb 1998,    oja:        Original version.
  59. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  60. static OSErr
  61. Read (IOParamPtr pb, DCtlPtr ctl)
  62. {
  63.     struct usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  64.  
  65.     //
  66.     //    if we have a unidirectional interface
  67.     //        report a read error
  68.     //        (only status supported by unidirectional is Centronics compatible)
  69.     //
  70.     pb->ioResult = paramErr;    // assume bad
  71.  
  72.     if ( usbprint->interface->interfaceProtocol == kUSBPrintClassProtocolUnidirectional )
  73.         pb->ioResult = readErr;
  74.     else if ( usbprint != NULL )
  75.         (*usbprint->qread)( pb, ctl, usbprint );    //    map the read param block into the usb param block
  76.  
  77.     return pb->ioResult;
  78.  
  79. }
  80.  
  81. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  82.     Name:        Write
  83.  
  84.     Input Parameters:
  85.         
  86.     Output Parameters:
  87.         <none>
  88.         
  89.     Description:
  90.         
  91.     Change History:
  92.         11 Jun 1998,    oja:        return pb->ioResult, not usbprint->out.usbStatus
  93.          4 Apr 1998,    oja:        Fix handshaking: do not set pb->ioResult
  94.         28 Feb 1998,    oja:        Original version.
  95. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  96. static OSErr
  97. Write (IOParamPtr pb, DCtlPtr ctl)
  98. {
  99.     struct usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  100.  
  101.     pb->ioResult = paramErr;    // assume bad
  102.  
  103.     if ( usbprint != NULL )
  104.         (*usbprint->qwrite)( pb, ctl, usbprint );    //    map the write param block into the usb param block
  105.  
  106.     return pb->ioResult;
  107. }
  108.  
  109. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  110.     Name:        AbortActive
  111.  
  112.     Input Parameters:
  113.         pb
  114.         ctl
  115.         
  116.     Output Parameters:
  117.         <none>
  118.         
  119.     Description:
  120.         
  121.     Change History:
  122.         4 Aug 1998,    oja:        Original version.
  123. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  124. static void
  125. AbortActive( CntrlParam *pb, DCtlPtr ctl )
  126. {
  127.     //        we need to wait here until the transaction is complete
  128.     struct usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  129.     struct USBPB                    *pActiveUSBIO;
  130.     IOParamPtr                        pActiveIO;
  131.  
  132.     if ( usbprint != NULL )
  133.     {
  134.         if ( pb->ioCRefNum == usbprint->outRefNum )
  135.         {
  136.             pActiveUSBIO = &usbprint->out;
  137.             pActiveIO = usbprint->writeDrvr.pb;
  138.         }
  139.         else
  140.         {
  141.             pActiveUSBIO = &usbprint->in;
  142.             pActiveIO = usbprint->readDrvr.pb;
  143.         }
  144.         if ( pActiveUSBIO->usbCompletion != NULL )
  145.         {
  146.             (*usbprint->qabort)( pb->ioCRefNum, usbprint );    //    cancel outstanding transactions
  147.             //
  148.             //    synchronize data toggle
  149.             // USB addendum, the endpoints of the pipe may be out of sync
  150.             //    a soft reset in the printer class should restore the data toggle
  151.             //
  152.             pb->csCode = kDrvrSoftReset;
  153.             (*usbprint->qstatus)( pb, ctl, usbprint );
  154.  
  155.         }
  156.     }
  157. }
  158.  
  159. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  160.     Name:        DRVROpen
  161.  
  162.     Input Parameters:
  163.         
  164.     Output Parameters:
  165.         <none>
  166.         
  167.     Description:
  168.         
  169.     Change History:
  170.         28 Feb 1998,    oja:        Original version.
  171. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  172.  
  173. pascal OSErr
  174. DRVROpen(CntrlParam *pb, DCtlPtr dce)
  175. {
  176.     return noErr;
  177. }
  178.  
  179. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  180.     Name:        DRVRClose
  181.  
  182.     Input Parameters:
  183.         
  184.     Output Parameters:
  185.         <none>
  186.         
  187.     Description:
  188.         
  189.     Change History:
  190.         28 Feb 1998,    oja:        Original version.
  191. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  192.  
  193. pascal OSErr
  194. DRVRClose(CntrlParam *pb, DCtlPtr ctl)
  195. {
  196.     return noErr;
  197. }
  198.  
  199. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  200.     Name:        DRVRStatus
  201.  
  202.     Input Parameters:
  203.         
  204.     Output Parameters:
  205.         <none>
  206.         
  207.     Description:
  208.         
  209.     Change History:
  210.         30 Jun 1998,    oja:        pass through messages for kDrvrCentronicsStatus,
  211.                                         kDrvr1284IdString,kDrvrSoftReset
  212.         28 Feb 1998,    oja:        Original version.
  213. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  214.  
  215. pascal OSErr
  216. DRVRStatus(CntrlParam *pb, DCtlPtr ctl)
  217. {
  218.     OSErr                err;
  219.     struct             usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  220.  
  221.     switch ( pb->csCode )
  222.     {
  223.     case kDrvrCentronicsStatus:    //  USB device: centronics status
  224.     case kDrvr1284IdString:     //  USB device: 1284 capability string
  225.     case kDrvrSoftReset:    //  USB device: soft reset
  226.         if ( usbprint != NULL )
  227.             (*usbprint->qstatus)( pb, ctl, usbprint );    //    map the status param block into the usb param block
  228.         err = pb->ioResult;
  229.         break;
  230.     case kDrvrNumDevices:    
  231.         err =  noErr;
  232.         break;
  233.     case 1:    
  234.     case 2:    // deprecated
  235.     default:
  236.         err = paramErr;
  237.         break;
  238.     }
  239.     return err;
  240. }
  241.  
  242. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  243.     Name:        DRVRControl
  244.  
  245.     Input Parameters:
  246.         csCode                        csParam
  247.         ------                        -------
  248.         kDrvrPrivateSetStorage    pointer to the USB device class storage
  249.  
  250.     Output Parameters:
  251.         <none>
  252.         
  253.     Description:
  254.         
  255.     Change History:
  256.         12 Jun 1998,    oja:        default to noErr (was uninitialized with killCode)
  257.         11 Jun 1998,    oja:        abort active usb transactions
  258.          4 Apr 1998,    oja        Removed unused code for private done i/o
  259.                                          pass error code to DrvrDone
  260.         28 Feb 1998,    oja:        Original version.
  261. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  262.  
  263. pascal OSErr
  264. DRVRControl(CntrlParam *pb, DCtlPtr ctl)
  265. {
  266.     OSErr                                err            = noErr;
  267.     struct usbPrinterPBStruct    *usbprint    = GetPrinterStruct( ctl );
  268.  
  269.     switch ( pb->csCode )
  270.     {
  271.     case killCode:
  272.         //
  273.         //    killIO is always handled as an immediate mode transaction
  274.         //
  275.         AbortActive( pb, ctl );
  276.         break;
  277.     case kDrvrPrivateSetStorage:
  278.         //
  279.         //    reference the class driver's private storage
  280.         //        it's not a handle, but devices.h thinks it should be
  281.         //
  282.         ctl->dCtlStorage = (Handle) *((Ptr *) &pb->csParam[0] );
  283.         break;
  284.     default:
  285.         err = paramErr;
  286.         break;
  287.     }
  288.     return err;
  289. }
  290.  
  291. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  292.     Name:        DRVRPrime
  293.  
  294.     Input Parameters:
  295.         
  296.     Output Parameters:
  297.         <none>
  298.         
  299.     Description:
  300.         
  301.     Change History:
  302.         28 Feb 1998,    oja:        Original version.
  303. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  304.  
  305. pascal OSErr
  306. DRVRPrime(CntrlParam *pb, DCtlPtr ctl)
  307. {
  308.     OSErr    err = paramErr;
  309.     //
  310.     //    switch on the low order byte to dispatch reads and writes
  311.     //
  312.     if ( (pb->ioTrap & kMaskLowByte) == aRdCmd )
  313.         err = Read( (IOParamPtr) pb, ctl );
  314.     else if ( (pb->ioTrap & kMaskLowByte) == aWrCmd )
  315.         err = Write( (IOParamPtr) pb, ctl );
  316.  
  317.     //
  318.     //    get the ioResult in case the completion routine has already executed
  319.     //    
  320.     if ( err == noErr )
  321.         err = pb->ioResult;
  322.  
  323.     return err;
  324. }
  325.  
  326. // eof
  327.